package com.axinfu.util.validq;

import com.axinfu.util.EmptyUtil;
import com.axinfu.util.validq.exception.ValidQException;

/**
 * 验证处理器
 * 该类提供了默认的处理器实现，自定义Validator可以继承此类而不需要实现接口重写所有实现
 * 改实现提供了一些常用字段供使用，并且这些字段的set方法是链式的
 *
 * @author zjn
 * @since 2022/3/23
 */
@SuppressWarnings("unused")
public abstract class BaseValidator implements Validator {

    /**
     * 字段（若有多级时如“filed_root.field_parent[0].field_son”）
     */
    private String field;

    /**
     * 短字段（多级时没有上级，如“field_son”）
     */
    private String shortField;

    /**
     * 字段名称（若有多级时如“跟节点.父列表[第1条].子节点”）
     */
    private String fieldName;

    /**
     * 短字段名称（多级时没有上级，如“子节点”）
     */
    private String shortFieldName;

    /**
     * 错误代码（来源于Validator）
     */
    private String errorCode;

    /**
     * 错误信息
     */
    private String errorMsg;

    public BaseValidator() {
    }

    public BaseValidator(String field, String fieldName) {
        this.field = field;
        this.shortField = field;
        this.fieldName = fieldName;
        this.shortFieldName = fieldName;
    }

    public BaseValidator(String field, String fieldName, String errorMsg) {
        this.field = field;
        this.shortField = field;
        this.fieldName = fieldName;
        this.shortFieldName = fieldName;
        this.errorMsg = errorMsg;
    }

    @Override
    public int index() {
        return 0;
    }

    @Override
    public boolean accept(ValidatorContext context, Object target) {
        return true;
    }

    @Override
    public boolean validate(ValidatorContext context, Object target) {
        return true;
    }

    @Override
    public void onException(Exception e, ValidatorContext context, Object target) {
        throw new ValidQException(e);
    }

    /**
     * 获取默认提示信息（第一个占位符为字段名称）
     *
     * @param errorMsg 包含占位符的错误信息
     * @return 预处理错误信息
     */
    protected String getDefaultMsg(String errorMsg) {
        String formatErrorMsg = this.getErrorMsg();
        formatErrorMsg = EmptyUtil.isNotEmptyOrDefault(formatErrorMsg, errorMsg);

        if (EmptyUtil.isNotEmpty(fieldName)) {
            formatErrorMsg = String.format(formatErrorMsg, fieldName);
        } else if (EmptyUtil.isNotEmpty(shortFieldName)) {
            formatErrorMsg = String.format(formatErrorMsg, shortFieldName);
        } else if (EmptyUtil.isNotEmpty(field)) {
            formatErrorMsg = String.format(formatErrorMsg, field);
        } else if (EmptyUtil.isNotEmpty(shortField)) {
            formatErrorMsg = String.format(formatErrorMsg, shortField);
        } else {
            throw new ValidQException("fieldName,shortFieldName,field,shortField,errorMsg has at least one");
        }
        if (EmptyUtil.isNotEmpty(errorCode)) {
            formatErrorMsg = String.format("%s:" + formatErrorMsg, errorCode);
        }
        return formatErrorMsg;
    }

    protected boolean fail(ValidatorContext context, Object target, String msgFormat) {
        String errorMsg = getDefaultMsg(msgFormat);
        errorMsg = context.replaceParams(errorMsg);

        ValidationError validationError = new ValidationError()
                .setValidator(this)
                .setField(this.getField())
                .setShortField(this.getShortField())
                .setFieldName(this.getFieldName())
                .setShortFieldName(this.getShortFieldName())
                .setErrorCode(this.getErrorCode())
                .setErrorMsg(errorMsg)
                .setErrorValue(target);
        context.addError(validationError);

        return false;
    }

    public String getField() {
        return field;
    }

    public BaseValidator setField(String field) {
        this.field = field;
        return this;
    }

    public String getShortField() {
        return shortField;
    }

    public BaseValidator setShortField(String shortField) {
        this.shortField = shortField;
        return this;
    }

    public String getFieldName() {
        return fieldName;
    }

    public BaseValidator setFieldName(String fieldName) {
        this.fieldName = fieldName;
        return this;
    }

    public String getShortFieldName() {
        return shortFieldName;
    }

    public BaseValidator setShortFieldName(String shortFieldName) {
        this.shortFieldName = shortFieldName;
        return this;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public BaseValidator setErrorCode(String errorCode) {
        this.errorCode = errorCode;
        return this;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public BaseValidator setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
        return this;
    }
}
